package com.tianlh.service.impl.redis;

import java.util.List;

import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

/**
 * @author 黑子
 * @Date 2018/1/1 16:43
 */
@Service
public class Transaction {

    /**
     * @param amount 还款金额
     * @Description:
     */
    private boolean transMethod(Jedis jedis, int amount) throws InterruptedException {

        // 银行卡可用余额100元
        int balance = 100;
        jedis.set("balance", String.valueOf(balance));
        // 信用卡欠费100元
        int debt = 100;
        jedis.set("debt", String.valueOf(debt));

        jedis.watch("balance");
        // watch再次更改这个key，则事务不会执行
        //jedis.set("balance", "10");

        balance = Integer.parseInt(jedis.get("balance"));
        if (balance < amount) {
            // 余额不足，由于此时并没有开始事务，则只需要去除watch命令对balance键的监控即可
            jedis.unwatch();
            return false;
        } else {
            List<Object> result = null;
            redis.clients.jedis.Transaction transaction = null;
            try {
                // 事务开始,所有命令Redis服务端会存储在一个队列中
                transaction = jedis.multi();
                transaction.decrBy("balance", amount);
                transaction.decrBy("debt", amount);
                // 事务执行,上述事务命令会在Redis服务端被原子执行
                result = transaction.exec();
            } catch (Exception e) {
                // Redis服务端队列中的命令会被清空，watch命令解除
                transaction.discard();
            }

            if (result.isEmpty()) {
                //事务提交失败, 说明在执行期间balance键的数据被修改过
                throw new InterruptedException();
            } else {
                //事务提交成功
                System.out.println("您的可用余额:" + jedis.get("balance"));
                System.out.println("您目前欠款:" + jedis.get("debt"));
                return true;
            }
        }
    }
}
